/*
 ============================================================================
 文件名 	: EasyBounceGameContainer.cpp
 描述		: EasyBounceGameContainer类的实现.
 ============================================================================
 */

//引用
#include <aknviewappui.h>
#include <aknnotewrappers.h>
#include <eikbtgpc.h>

#include <EasyBounce.rsg>
#include <easybounceballs.mbg>

#include "coedef.h"
#include "EasyBounceAppUi.h"
#include "EasyBounceGameContainer.h"
#include "Ball.h"
#include "Engine.h"
#include "EasyBounceGameView.h"

_LIT(KBmpFile, "\\resource\\apps\\easybounceballs.mbm");

// ================= 成员函数 =======================

// -----------------------------------------------------------------------------
// CEasyBounceGameContainer::CEasyBounceGameContainer()
// C++默认构造函数.
// -----------------------------------------------------------------------------
//
CEasyBounceGameContainer::CEasyBounceGameContainer()
	{
	iWoodenBall = NULL;
	iBall = iBallMask = NULL;
	}

// -----------------------------------------------------------------------------
// CEasyBounceGameContainer::ConstructL()
// 两阶段构造函数.
// -----------------------------------------------------------------------------
//
void CEasyBounceGameContainer::ConstructL()
    {
    CreateWindowL();
	const TDesC& file = KBmpFile;
	AknIconUtils::CreateIconL(iBall, iBallMask, file, 
				(TInt)EMbmEasybounceballsWooden_ball, (TInt)EMbmEasybounceballsWooden_ball_mask);
	iWoodenBall = new (ELeave)CEikImage;
	iWoodenBall->SetPicture( iBall, iBallMask );
	iWoodenBall->SetAlignment( EHCenterVCenter );
	iWoodenBall->SetExtent( TPoint(168,40), TSize(24,24) );
	iBgContext = CAknsBasicBackgroundControlContext::NewL( 
	   			KAknsIIDQsnBgAreaMain, Rect(), ETrue);
    ActivateL();
    }

// -----------------------------------------------------------------------------
// CEasyBounceGameContainer::NewL()
// 两阶段构造函数.
// -----------------------------------------------------------------------------
//
CEasyBounceGameContainer* CEasyBounceGameContainer::NewL()
	{
	CEasyBounceGameContainer* self = new (ELeave)CEasyBounceGameContainer;
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop();
	return self;
	}

// ---------------------------------------------------------------------------
// CEasyBounceGameContainer::~CEasyBounceGameContainer()
// 析构函数.
// ---------------------------------------------------------------------------
//
CEasyBounceGameContainer::~CEasyBounceGameContainer()
    {
	delete  iWoodenBall;
	iWoodenBall = NULL;
	iBall = NULL;
	iBallMask = NULL;
	delete iBgContext;
	iBgContext = NULL;
    }

// ---------------------------------------------------------
// CEasyBounceGameContainer::SizeChanged()
// 此函数在控件大小发生变化时被框架调用.
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::SizeChanged()
    {
    //重置皮肤
    if(iBgContext)
		{
		//重置背景区域
		iBgContext->SetRect(Rect());
        
		//把Container在屏幕上的位置传递给iBgContext
		if ( &Window() )
			{
			iBgContext->SetParentPos( PositionRelativeToScreen() );
			}
		}
    
    //重新计算控件布局
	CaculateLayout();
    }

// ---------------------------------------------------------
// CEasyBounceGameContainer::CountComponentControls()
// 此函数被框架调用，返回容器中的控件个数
// ---------------------------------------------------------
//
TInt CEasyBounceGameContainer::CountComponentControls() const
    {
    return ( int ) ELastControl; 
    }

// ---------------------------------------------------------
// CEasyBounceGameContainer::ComponentControl()
// 此函数被框架调用，返回指定的控件
// ---------------------------------------------------------
//
CCoeControl* CEasyBounceGameContainer::ComponentControl(TInt aIndex) const
    {
	switch ( aIndex )
		{
		case EWoodenBallImage:
			{
			return iWoodenBall;
			}
		default:
			return NULL;
		}
    }


// ---------------------------------------------------------
// CEasyBounceGameContainer::OffeKeyEventL()
// 处理按键事件
// ---------------------------------------------------------
//
TKeyResponse CEasyBounceGameContainer::OfferKeyEventL(
    const TKeyEvent& aKeyEvent, TEventCode aType)
    {
    TKeyResponse ret;
    
    //如果用户按的是OK键，则暂停或恢复游戏，否则不进行处理
    if ((aType == EEventKey)&&(aKeyEvent.iCode == EKeyDevice3))
    	{
        CEngine* engine = CEngine::Instance();
    	engine->PauseOrResume();
    	ret = EKeyWasConsumed;
    	}
    else 
    	{
    	ret = EKeyWasNotConsumed;
    	}

    return ret;
    }

// ---------------------------------------------------------
// CEasyBounceGameContainer::Draw()
// 每次刷新屏幕的时候，重新绘制直线以及背景等
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::Draw(const TRect& aRect) const
    {
	CWindowGc& gc = SystemGc();
	gc.Clear( aRect );
	
    //MAknsSkinInstance* skin = AknsUtils::SkinInstance();
    //MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
    //AknsDrawUtils::Background( skin, cc, this, gc, aRect );
    gc.SetPenColor( KRgbDarkCyan );
    gc.SetPenSize( TSize(1,4) );
    gc.DrawLine( iLineStart, iLineEnd );

    }

// ---------------------------------------------------------
// CEasyBounceGameContainer::HandleControlEventL()
// 处理控件事件    
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::HandleControlEventL(
    CCoeControl* /*aControl*/,TCoeEvent /*aEventType*/)
    {
    //空实现
    }

// ---------------------------------------------------------
// CEasyBounceGameContainer::HandlePointerEventL()
// 处理触笔事件
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::HandlePointerEventL( const TPointerEvent& aPointerEvent )
	{
	CEngine* game = CEngine::Instance();
	TRect modelRect = game->GetGameRoom();
	TRect viewRect = Rect();
	
    switch( aPointerEvent.iType )
    	{
    	//按下触笔的时候设置线段的第一个端点
    	case TPointerEvent::EButton1Down:
    		{
    		TInt xx = ( aPointerEvent.iPosition.iX * modelRect.Width()) / viewRect.Width();
    		TInt yy = (( viewRect.Height() - aPointerEvent.iPosition.iY ) * modelRect.Height()) / viewRect.Height();
			game->GetLine()->SetStart( TPoint( xx,yy ) );
			game->GetLine()->SetEnd( TPoint( xx,yy ) );
    		break;
    		}
    	//提起触笔的时候设置线段的第二个端点
    	case TPointerEvent::EButton1Up:
    		{
    		TInt xx = ( aPointerEvent.iPosition.iX * modelRect.Width()) / viewRect.Width();
    		TInt yy = (( viewRect.Height() - aPointerEvent.iPosition.iY ) * modelRect.Height()) / viewRect.Height();
    		game->GetLine()->SetEnd( TPoint( xx, yy) );
    		break;
    		}
    	default:
    	    break;
    	}
	}

// ---------------------------------------------------------
// CEasyBounceGameContainer::GameChanged()
// 游戏每执行一步，都需要重新绘制屏幕
// 此函数是GameObserver接口函数的实现，游戏引擎每执行一步都会调用这个方法
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::GameChanged( CEngine* /*aGame*/ )
	{
	CaculateLayout();
	DrawDeferred();
	}

// ---------------------------------------------------------
// CEasyBounceGameContainer::GameOver()
// 此函数是GameObserver接口函数的实现，游戏结束时此函数会被调用
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::GameOver( CEngine* /*aGame*/ )
	{
	CaculateLayout();
	DrawDeferred();
	
    CEasyBounceAppUi* appUi = (CEasyBounceAppUi*)iEikonEnv->AppUi();
    TUid gameViewId = TUid::Uid(EGameViewId); 
    CEasyBounceGameView* view = (CEasyBounceGameView*)appUi->View(gameViewId);
	view->HandleCommandL( ECmdOver );
	}

// ---------------------------------------------------------
// CEasyBounceGameContainer::GamePaused()
// 此函数是GameObserver接口函数的实现，游戏暂停时此函数会被调用
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::GamePaused( CEngine* /*aGame*/ )
	{
	//空实现
	}

// ---------------------------------------------------------
// CEasyBounceGameContainer::BallHitsLine()
// 此函数是GameObserver接口函数的实现，小球撞击到直线时此函数会被调用
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::BallHitsLine( CEngine* /*aGame*/ )
    {
    //空实现
    }

// ---------------------------------------------------------
// CEasyBounceGameContainer::HandleResourceChange()
// 资源发生变化时被框架调用  
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::HandleResourceChange( TInt /*aType*/ )
	{
	//获取view的指针
	CAknViewAppUi* appui = static_cast<CAknViewAppUi*>( iEikonEnv->AppUi() );
	
	//让view来设置container的区域大小
	appui->View(KGameViewId)->HandleViewRectChange();
	}

// ---------------------------------------------------------
// CEasyBounceGameContainer::CaculateLayout()
// 重新计算小球、直线在界面上的位置 
// ---------------------------------------------------------
//
void CEasyBounceGameContainer::CaculateLayout()
	{
	CEngine* game = CEngine::Instance();
	TRect modelRect = game->GetGameRoom();
	TRect viewRect = Rect();
	CBall* ball = game->GetBall();
	TInt xx = TInt( ( (ball->GetPos().iX + 0.5f) * viewRect.Width()) / modelRect.Width() );
	TInt yy = TInt( viewRect.Height() - ( (ball->GetPos().iY + 0.5f) * viewRect.Height()) / modelRect.Height() );
		
	iWoodenBall->SetExtent( TPoint(xx -12 ,yy -12 ), iWoodenBall->Size() );
	iLineStart.iX = ( game->GetLine()->GetStart().iX * viewRect.Width()) / modelRect.Width();
	iLineStart.iY = viewRect.Height() - ( game->GetLine()->GetStart().iY * viewRect.Height()) / modelRect.Height();
	iLineEnd.iX = ( game->GetLine()->GetEnd().iX * viewRect.Width()) / modelRect.Width();
	iLineEnd.iY = viewRect.Height() - ( game->GetLine()->GetEnd().iY * viewRect.Height()) / modelRect.Height();	
	}

// ---------------------------------------------------------
// CEasyBounceGameContainer::MopSupplyObject()
// 此函数与其他函数一起用来使程序支持皮肤     
// ---------------------------------------------------------
//
TTypeUid::Ptr CEasyBounceGameContainer::MopSupplyObject( TTypeUid aId )
	{
	if (iBgContext )
		 {
		   return MAknsControlContext::SupplyMopObject( aId, iBgContext );
		 }
	return CCoeControl::MopSupplyObject(aId);
	}


// 文件结束  
